/*
Copyright (c) 2009, Luke Berndt
All rights reserved.
 
 * More Information: http://www.tagflo.com

Redistribution and use in source and binary forms, with or without modification, are permitted 
provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this list of conditions 
  and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright notice, this list of conditions 
  and the following disclaimer in the documentation and/or other materials provided with the distribution.

* Neither the name of RoboTastic Software nor the names of its contributors may be used to endorse or 
  promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED 
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
POSSIBILITY OF SUCH DAMAGE.
*/


using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace TagFlo
{
    /// <summary>
    /// Interaction logic for PhotoGrid.xaml
    /// </summary>

    public partial class PhotoGrid : ListBox
    {
        private Point m_StartPoint;
        private bool m_IsDown;
        private Photo m_OriginalElement;
        private Photo[] selectedPhotos;
       // private DropPreviewAdorner m_OverlayElement;
       // private System.Xml.XmlElement m_RemoteElement;
       

        public PhotoGrid()
        {
            InitializeComponent();
            this.PreviewMouseLeftButtonDown += new System.Windows.Input.MouseButtonEventHandler(PhotoGrid_PreviewMouseLeftButtonDown);
            this.PreviewMouseMove += new System.Windows.Input.MouseEventHandler(PhotoGrid_PreviewMouseMove);
            this.PreviewDragOver += new DragEventHandler(PhotoGrid_PreviewDragOver);
            this.PreviewDrop += new DragEventHandler(PhotoGrid_PreviewDrop);
            this.PreviewDragEnter += new DragEventHandler(PhotoGrid_PreviewDragEnter);
         //   this.PreviewDragLeave += new DragEventHandler(PhotoGrid_PreviewDragLeave);
            
        }

        private void PhotoItemMenuEdit_Click(object sender, RoutedEventArgs e)
        {


            System.Windows.Controls.MenuItem mi = (System.Windows.Controls.MenuItem)sender;
            System.Windows.Controls.ContextMenu menu = (System.Windows.Controls.ContextMenu)mi.Parent;
            //menu.PlacementTarget

            DataRowView drv = (DataRowView)this.SelectedItem;
            string filePath = drv.Row["Path"].ToString();
            ProcessStartInfo startInfo = new ProcessStartInfo(filePath);

            foreach (String verb in startInfo.Verbs)
            {
                if (verb == "edit")
                {
                    startInfo.Verb = "edit";
                    Process.Start(startInfo);
                }
            }


            //  System.Diagnostics.Process.Start(filePath);
        }

        private void PhotoItemMenuOpen_Click(object sender, RoutedEventArgs e)
        {


            System.Windows.Controls.MenuItem mi = (System.Windows.Controls.MenuItem)sender;
            System.Windows.Controls.ContextMenu menu = (System.Windows.Controls.ContextMenu)mi.Parent;
            //menu.PlacementTarget

            Photo p = (Photo)this.SelectedItem;
            string filePath = p.FullFilename;

            System.Diagnostics.Process.Start(filePath);
        }


        private void PhotoGrid_PreviewMouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            m_OriginalElement = GetElementFromPoint(this, e.GetPosition(this));
            if (m_OriginalElement == null)
            {
                return;
            }
            m_IsDown = true;
            m_StartPoint = e.GetPosition(this);
        }

        private Photo GetElementFromPoint(ListBox box, Point point)
        {
            UIElement element = (UIElement)box.InputHitTest(point);
            while (true)
            {
                if (element == box)
                {
                    return null;
                }
                object item = box.ItemContainerGenerator.ItemFromContainer(element);
                bool itemFound = !(item.Equals(DependencyProperty.UnsetValue));
                if (itemFound)
                {
                    return item as Photo;// as System.Xml.XmlElement;
                }
                element = (UIElement)VisualTreeHelper.GetParent(element);
            }
        }

        private void PhotoGrid_PreviewMouseMove(object sender, System.Windows.Input.MouseEventArgs e)
        {
            if (m_IsDown)
            {
                if (Math.Abs(e.GetPosition(this).X - m_StartPoint.X) > SystemParameters.MinimumHorizontalDragDistance && Math.Abs(e.GetPosition(this).Y - m_StartPoint.Y) > SystemParameters.MinimumVerticalDragDistance)
                {
                    DragStarted();
                }
            }
        }

        private void DragStarted()
        {
            m_IsDown = false;
            int count = this.SelectedItems.Count;
            selectedPhotos = new Photo[count];
            for (int i=0; i<count; i++)
            {
                selectedPhotos[i] = (Photo) this.SelectedItems[i];
            }
            DragDropEffects effects = DragDrop.DoDragDrop(this,selectedPhotos, DragDropEffects.Copy);

        }
/*
        private void DragMoved()
        {
            Point currentPosition = System.Windows.Input.Mouse.GetPosition(this);
            m_OverlayElement.LeftOffset = currentPosition.X - m_StartPoint.X;
            m_OverlayElement.TopOffset = currentPosition.Y - m_StartPoint.Y;
        }
        */
        private void PhotoGrid_PreviewDragOver(object sender, System.Windows.DragEventArgs e)
        {
            if (!(UpdateEffects(e)))
            {
                return;
            }
            Point currentPosition = (Point)e.GetPosition((IInputElement) this);
            /* m_OverlayElement.LeftOffset = currentPosition.X;
             m_OverlayElement.TopOffset = currentPosition.Y;*/
            e.Handled = true;
        }

        private void PhotoGrid_PreviewDrop(object sender, System.Windows.DragEventArgs e)
        {
            if (!(UpdateEffects(e)))
            {
                return;
            }
            /*  XmlDataProvider dataProvider = (XmlDataProvider)FindResource("MyData");
              System.Xml.XmlDocument document = dataProvider.Document;
              System.Xml.XmlElement node = (System.Xml.XmlElement)dataProvider.Document.ImportNode(m_RemoteElement, true);
              dataProvider.Document.GetElementsByTagName("Section")[0].AppendChild(node);
              AdornerLayer.GetAdornerLayer((System.Windows.Media.Visual)this.Content).Remove(m_OverlayElement);
              m_RemoteElement = null;
              m_OverlayElement = null;*/
            e.Handled = true;
        }

        private void PhotoGrid_PreviewDragEnter(object sender, System.Windows.DragEventArgs e)
        {
            if (!(UpdateEffects(e)))
            {
                return;
            }
            /* string serializedObject = (string)e.Data.GetData(m_MyFormat.Name);
             System.Xml.XmlDocument document = new System.Xml.XmlDocument();
             document.LoadXml(serializedObject);
             m_RemoteElement = document.DocumentElement;
             ContentPresenter presenter = new ContentPresenter();
             presenter.Content = m_RemoteElement;
             presenter.ContentTemplate = this.ItemTemplate;
             AdornerLayer layer;
             m_OverlayElement = new DropPreviewAdorner((UIElement)this.Content, presenter);
             layer = AdornerLayer.GetAdornerLayer((System.Windows.Media.Visual)this.Content);
             layer.Add(m_OverlayElement);
             e.Handled = true;*/
        }
        /*
        private void PhotoGrid_PreviewDragLeave(object sender, System.Windows.DragEventArgs e)
        {
            if (m_OverlayElement == null)
            {
                return;
            }*/
            /* AdornerLayer.GetAdornerLayer((System.Windows.Media.Visual)this.Content).Remove(m_OverlayElement);
             m_OverlayElement = null;
             m_RemoteElement = null;*/
     /*       e.Handled = true;
        }
    */
        private bool UpdateEffects(System.Windows.DragEventArgs e)
        {
            
            if ((e.AllowedEffects & DragDropEffects.Copy) == 0 && (e.AllowedEffects & DragDropEffects.Move) == 0)
            {
                e.Effects = DragDropEffects.None;
                return false;
            }
            if ((e.AllowedEffects & DragDropEffects.Copy) != 0 && (e.AllowedEffects & DragDropEffects.Move) != 0)
            {
                if ((e.KeyStates & DragDropKeyStates.ControlKey) != 0)
                {
                    e.Effects = DragDropEffects.Copy;
                }
                else
                {
                    e.Effects = DragDropEffects.Move;
                }
            }
            else
            {
                e.Effects = e.AllowedEffects & ((DragDropEffects.Copy | DragDropEffects.Move));
            }
            return true;
        }

        class DropPreviewAdorner : Adorner
        {

            public DropPreviewAdorner(UIElement adornedElement, UIElement adorningElement)
                : base(adornedElement)
            {
                VisualBrush brush = new VisualBrush(adorningElement);
                m_Child = new Rectangle();
                m_Child.Width = adorningElement.RenderSize.Width;
                m_Child.Height = adorningElement.RenderSize.Height;
                m_Child.Fill = brush;
                m_Child.IsHitTestVisible = false;
                System.Windows.Media.Animation.DoubleAnimation animation;
                animation = new System.Windows.Media.Animation.DoubleAnimation(0.3, 1, new Duration(TimeSpan.FromSeconds(1)));
                animation.AutoReverse = true;
                animation.RepeatBehavior = System.Windows.Media.Animation.RepeatBehavior.Forever;
                brush.BeginAnimation(System.Windows.Media.Brush.OpacityProperty, animation);
            }
            private Rectangle m_Child;
            private double m_LeftOffset;
            private double m_TopOffset;

            protected override System.Windows.Size MeasureOverride(System.Windows.Size constraint)
            {
                m_Child.Measure(constraint);
                return m_Child.DesiredSize;
            }

            protected override System.Windows.Size ArrangeOverride(System.Windows.Size finalSize)
            {
                m_Child.Arrange(new Rect(finalSize));
                return finalSize;
            }

            protected override System.Windows.Media.Visual GetVisualChild(int index)
            {
                return m_Child;
            }

            protected override int VisualChildrenCount
            {
                get
                {
                    return 1;
                }
            }

            public double LeftOffset
            {
                get
                {
                    return m_LeftOffset;
                }
                set
                {
                    m_LeftOffset = value;
                    UpdatePosition();
                }
            }

            public double TopOffset
            {
                get
                {
                    return m_TopOffset;
                }
                set
                {
                    m_TopOffset = value;
                    UpdatePosition();
                }
            }

            private void UpdatePosition()
            {
                AdornerLayer adornerLayer = this.Parent as AdornerLayer;
                if (adornerLayer != null)
                {
                    adornerLayer.Update(AdornedElement);
                }
            }

        }

    }
}